home *** CD-ROM | disk | FTP | other *** search
- /* Copyright ) Darin Johnson, 1989 */
-
- /* DoRun.c -- I met her on a Monday, and my heart stood still... */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <intuition/intuition.h>
- #include <workbench/icon.h>
- #include <workbench/startup.h>
- #include <workbench/workbench.h>
- #include <functions.h>
- #include "mymenu.h"
-
- #ifdef AZTEC_C
- #define strlen _BUILTIN_strlen
- #define strcpy _BUILTIN_strcpy
- #endif
-
- #ifdef DO_PATH
- #define CMDSIZ 256
- #define CBUFSZ 80
- #endif
-
- extern struct Process *MyProcess;
-
- /* text to put into autorequesters */
- struct IntuiText err_nocmd = { 0,1,JAM2, 20,10, NULL,
- (UBYTE*)"MyMenu: can't execute command", NULL };
- struct IntuiText err_nomem = { 0,1,JAM2, 20,10, NULL,
- (UBYTE*)"MyMenu: out of memory!", NULL };
- struct IntuiText err_noinfo = { 0,1,JAM2, 20,10, NULL,
- (UBYTE*)"MyMenu: can't open info file", NULL };
- struct IntuiText err_notool = { 0,1,JAM2, 20,10, NULL,
- (UBYTE*)"MyMenu: not a tool or project", NULL };
- struct IntuiText req_neg = { 0,1,JAM2, 7,3, NULL,
- (UBYTE*)"Aw, shucks", NULL };
-
- /* process a menu item */
- int run_item(item)
- struct ext_MenuItem *item;
- {
- if (item->cmd) {
- if (item->type == 'C') {
- do_clirun(item->cmd, item->args);
- }
- #ifdef DO_WB
- else if (item->type == 'W') {
- do_wbrun(item->cmd);
- }
- #endif
- }
- }
-
- #ifdef DO_PATH
- char *FindIt();
- #endif
-
- /* execute a CLI command */
- do_clirun(cmd, args)
- char *cmd, *args;
- {
- struct FileHandle *NilFh, *Open();
- register char *buf;
- register short siz;
-
- #ifdef DO_PATH
- cmd = FindIt(cmd);
- #endif
- if (cmd==NULL) {
- AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
- return;
- }
-
- siz = 32 + strlen(cmd);
- if (args)
- siz += strlen(args);
- buf = (char *)AllocMem(siz, MEMF_PUBLIC);
- if (buf==NULL) {
- AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
- return;
- }
- strcpy(buf, "RUN <NIL: >NIL: \"");
- strcat(buf, cmd);
- strcat(buf, "\" <NIL: >NIL: ");
- if (args)
- strcat(buf, args);
-
- NilFh = Open("NIL:", MODE_NEWFILE);
- if (NilFh) {
- Execute(buf, NULL, NilFh);
- Close(NilFh);
- }
- FreeMem(buf, siz);
- }
-
- /* procedures to support running WorkBench programs */
-
- #ifdef DO_WB
- extern int wb_cnt;
- extern struct MsgPort *wb_reply_port;
-
- /* create (and allocate) a copy of a string */
- char *copystr(str) {
- char *tmpstr;
- if (!str)
- return NULL;
- tmpstr = (char *)AllocMem(strlen(str)+1, MEMF_PUBLIC);
- strcpy(tmpstr, str);
- return tmpstr;
- }
-
- /* Free up space used by a workbench startup message. Called whenever
- a workbench program replies to the startup message, and whenever
- do_wbrun() gets an error */
- wbfree(WBStartup)
- struct WBStartup *WBStartup;
- {
- register BPTR lock;
- register int i;
- register char *cp;
- if (WBStartup != NULL) {
- if (WBStartup->sm_ArgList != NULL) {
- for (i=0; i<WBStartup->sm_NumArgs; i++) {
- if ((lock=WBStartup->sm_ArgList[i].wa_Lock) != NULL) {
- UnLock(lock);
- }
- if ((cp=WBStartup->sm_ArgList[i].wa_Name) != NULL)
- FreeMem(cp, strlen(cp)+1);
- }
- FreeMem(WBStartup->sm_ArgList,
- sizeof(struct WBArg)*WBStartup->sm_NumArgs);
- }
- if (WBStartup->sm_Segment != NULL) {
- UnLoadSeg(WBStartup->sm_Segment);
- }
- if ((cp=WBStartup->sm_ToolWindow) != NULL)
- FreeMem(cp, strlen(cp)+1);
- FreeMem(WBStartup, sizeof(struct WBStartup));
- }
- }
-
- /* take the path passed, and split it into a lock and name,
- suitable for putting into a WBArg structure */
- split_path(path, dir_lock, name)
- char *path, **name;
- BPTR *dir_lock;
- {
- register char *p;
- register BPTR lock;
-
- for (p=path, *name=path; *p; p++)
- if (*p == '/' || *p == ':')
- *name = p+1;
- lock = (BPTR)Lock(path, ACCESS_READ);
- if (lock) {
- *dir_lock = (BPTR)ParentDir(lock);
- UnLock(lock);
- } else {
- *dir_lock = (BPTR)DupLock(MyProcess->pr_CurrentDir);
- }
- }
-
- /* load and run a workbench program */
- int do_wbrun(cmd)
- char *cmd;
- {
- BPTR lock, oldlock;
- struct WBStartup *WBStartup;
- struct DiskObject *disk_object;
- char argc, *name, buf[128];
- char error;
-
- disk_object = WBStartup = NULL;
- lock = oldlock = NULL;
- name = NULL;
- error = TRUE; /* assume the worst */
-
- /* allocate the startup message */
- if ((WBStartup = (struct WBStartup *)AllocMem(sizeof(struct WBStartup),
- MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
- AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
- return TRUE; /* don't go to finish:, nothing allocated yet */
- }
- #ifdef DO_PATH
- if ((cmd = FindIt(cmd)) == NULL)
- goto finish;
- #endif
-
- /* find the directory and name of the program to run */
- split_path(cmd, &lock, &name);
- if (lock == NULL) {
- AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
- goto finish;
- }
-
- /* try to load in the .info file */
- oldlock = (BPTR)CurrentDir(lock);
- if ((disk_object = GetDiskObject(name)) == NULL) {
- AutoRequest(NULL, &err_noinfo, NULL, &req_neg, 0,0,300,60);
- goto finish;
- }
-
- /* allocate the WBArgs - if we are a tool, we allocate one */
- /* of these, else two (one for tool, one for project) */
- if (disk_object->do_Type == WBTOOL) {
- if ((WBStartup->sm_ArgList = (struct WBArg *)
- AllocMem(sizeof(struct WBArg), MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
- AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
- goto finish;
- }
- WBStartup->sm_NumArgs = 1;
- } else if (disk_object->do_Type == WBPROJECT) {
- if ((WBStartup->sm_ArgList = (struct WBArg *)
- AllocMem(sizeof(struct WBArg)*2, MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
- AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
- goto finish;
- }
- WBStartup->sm_NumArgs = 2;
- /* fill in arg #2 with the info we already have */
- WBStartup->sm_ArgList[1].wa_Lock = (BPTR)lock;
- WBStartup->sm_ArgList[1].wa_Name = copystr(name);
- /* now find the tool */
- strcpy(buf, disk_object->do_DefaultTool);
- split_path(buf, &lock, &name);
- FreeDiskObject(disk_object);
- CurrentDir(lock);
- if ((disk_object = GetDiskObject(name)) == NULL) {
- AutoRequest(NULL, &err_noinfo, NULL, &req_neg, 0,0,300,60);
- goto finish;
- }
- /* we have to have a tool at this point - or else */
- if (disk_object->do_Type != WBTOOL) {
- AutoRequest(NULL, &err_notool, NULL, &req_neg, 0,0,300,60);
- goto finish;
- }
- }
-
- /* fill in arguments */
- WBStartup->sm_ArgList[0].wa_Lock = (BPTR)lock;
- WBStartup->sm_ArgList[0].wa_Name = copystr(name);
-
- /* initialize rest of startup message */
- WBStartup->sm_Message.mn_ReplyPort = wb_reply_port;
- WBStartup->sm_Message.mn_Length = sizeof(struct WBStartup);
- WBStartup->sm_Message.mn_Node.ln_Type = NT_MESSAGE;
- WBStartup->sm_ToolWindow = copystr(disk_object->do_ToolWindow);
-
- /* get a decent stack size, there are a few progs that set this to zero */
- if (disk_object->do_StackSize < 4000)
- disk_object->do_StackSize = 4000;
-
- /* load in the program */
- if ((WBStartup->sm_Segment = (BPTR)LoadSeg(name)) == NULL) {
- AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
- goto finish;
- }
-
- /* create process */
- if ((WBStartup->sm_Process = (struct MsgPort *)CreateProc(name,
- 0, WBStartup->sm_Segment, disk_object->do_StackSize)) == NULL) {
- AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
- goto finish;
- }
- /* everything's ok -- start 'er up */
- PutMsg(WBStartup->sm_Process, WBStartup);
- error = FALSE;
- wb_cnt++; /* keep track of unreplied startup messages */
- finish:
- if (disk_object) FreeDiskObject(disk_object);
- if (oldlock) CurrentDir(oldlock);
- if (error)
- wbfree(WBStartup);
- return error;
- }
- #endif
-
- #ifdef DO_PATH
- /* This section is largely taken from RunBack
- (which was largely taken from which.c by Carolyn Scheppner).
- This handles path searching.
- */
-
- /***** currently these routines can cause guru's
- Run a workbench program, and then run a program that
- uses the path searching - often causes a Guru, but can't
- tell why. If the wbfree() does NOT free its locks, then
- it doesn't guru.
- *****/
-
- static char sbuf[CMDSIZ];
-
- /* search for a command in our path */
- char *FindIt(command)
- char *command;
- {
- BOOL getPath();
- struct Path *path;
- struct FileInfoBlock *fib;
- BPTR lock, startcd;
- BOOL Found, InitialCD;
-
- /* Were we given full path in command name (':' in name) ? */
- {
- register char *p;
- for (p=command; *p; p++) {
- if (*p == ':') {
- lock = (BPTR)Lock(command,ACCESS_READ);
- if (lock==NULL)
- return NULL; /* command not found */
- UnLock(lock);
- return command;
- }
- }
- }
-
- /* allocate this for Examine() calls */
- fib = (struct FileInfoBlock *)
- AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC|MEMF_CLEAR);
- if (fib == NULL)
- return NULL;
-
- /* Check current directory */
- Found = getPath(command, fib, sbuf);
-
- /* Check along paths */
- if (!Found) {
- InitialCD = TRUE;
-
- for (path = MM->CLI_path; (path) && (!Found); path = path->path_Next) {
- /* CD to each path */
- lock = (BPTR)CurrentDir(path->path_Lock);
- if (InitialCD) {
- startcd = lock; InitialCD = FALSE;
- }
- /* See if command is there */
- Found = getPath(command, fib, sbuf);
- }
- /* If we CD'd anywhere, restore initial CD */
- if (!InitialCD)
- CurrentDir(startcd);
- }
-
- /* Check C: */
- if (!Found) {
- char cbuf[CBUFSZ];
- strcpy(cbuf,"C:");
- strcpy(&cbuf[2], command);
- Found = getPath(cbuf, fib, sbuf);
- }
-
- /* Free fib */
- if (fib != NULL)
- FreeMem(fib, sizeof(struct FileInfoBlock));
-
- if (Found)
- return(sbuf);
- else
- return(NULL);
- }
-
- /* see if command is in current directory, if so, return path name
- in 'buf' */
- BOOL
- getPath(command,fib,buf)
- char *command;
- struct FileInfoBlock *fib;
- char *buf;
- {
- BPTR lock;
- BOOL success = FALSE;
- if (lock = (BPTR)Lock(command, ACCESS_READ)) {
- if (Examine(lock, fib)) {
- buildPath(lock, fib, buf);
- success = TRUE;
- }
- UnLock(lock);
- }
- return(success);
- }
-
- /* builds up a path name from 'inlock' and returns it in 'buf' */
- buildPath(inlock,fib,buf)
- BPTR inlock;
- struct FileInfoBlock *fib;
- char *buf;
- {
- int i;
- BPTR lock, oldlock;
- buf[0] = NULL;
- lock = inlock;
-
- /* follow path up, building up name as we go */
- while (lock) {
- if (Examine(lock, fib)) {
- if (fib->fib_FileName[0] > ' ') {
- if (buf[0]) insert(buf,"/");
- insert(buf,fib->fib_FileName);
- }
- }
- oldlock = lock;
- lock = (BPTR)ParentDir(lock);
- /* make sure we don't unlock the lock passed to us */
- if (oldlock != inlock)
- UnLock(oldlock);
- }
-
- /* fix up path name */
- if (fib->fib_FileName[0] > ' ') {
- register char *p;
- for (p=buf; *p; p++) {
- if (*p == '/') {
- *p = ':';
- break;
- }
- }
- } else
- insert(buf,"RAM:"); /* why? */
- }
-
- /* insert 's' at the beginning of 'buf' */
- insert(buf,s)
- char *buf,*s;
- {
- char tmp[CMDSIZ];
- strcpy(tmp, buf);
- strcpy(buf, s);
- strcpy(&buf[strlen(s)], tmp);
- }
- #endif
-